package com.gsn.engine.gdx.assets;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.List;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.assets.loaders.resolvers.InternalFileHandleResolver;
import com.badlogic.gdx.assets.loaders.resolvers.ResolutionFileResolver;
import com.badlogic.gdx.assets.loaders.resolvers.ResolutionFileResolver.Resolution;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.ParticleEffect;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
import com.gsn.engine.GsnException;

public abstract class GsnManagerTexture {
	private final String tag = this.getClass().getName();
	public boolean loaded;
	// public AssetManager manager;
	public boolean assigned = false;
	public Resolution[] resolutions = { new Resolution(240, 320, "240320"), new Resolution(480, 800, "480800") };
	public ResolutionFileResolver resolver = new ResolutionFileResolver(new InternalFileHandleResolver(), resolutions);
	public AssetManager manager = new AssetManager(resolver);
	public float scale;

	public void autoAssignAtlas(TextureAtlas atlas) {
		Object obj = this;
		Field[] fields = obj.getClass().getFields();
		for (int i = 0; i < fields.length; i++) {
			Field f = fields[i];
			if (Modifier.isPublic(f.getModifiers()) && !Modifier.isStatic(f.getModifiers())) {
				try {
					if (f.get(obj) != null)
						continue;
					if (f.getType() == AtlasRegion.class) {
						AtlasRegion region = atlas.findRegion(f.getName());
						f.set(obj, region);
						if (region == null) {
							Gdx.app.log(tag, "region = null voi : " + f.getName());
						}
					}

					if (f.getType() == List.class) {
						List<AtlasRegion> region = atlas.findRegions(f.getName());
						f.set(obj, region);
						if (region == null) {
							Gdx.app.log(tag, "List<region> = null voi : " + f.getName());
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	public boolean checkNullContent() {
		Object obj = this;
		boolean ok = true;
		Field[] fields = obj.getClass().getFields();
		for (int i = 0; i < fields.length; i++) {
			Field f = fields[i];
			if (Modifier.isPublic(f.getModifiers()) && !Modifier.isStatic(f.getModifiers())) {
				try {
					Class<?> type = f.getType();
					if (type == AtlasRegion.class || type == List.class || type == BitmapFont.class || type == ParticleEffect.class) {
						if (f.get(obj) == null) {
							ok = false;
							Gdx.app.log(tag, "region = null voi : " + f.getName());
						}
					}

					if (f.getType() == List.class) {

						List<AtlasRegion> list = (List<AtlasRegion>) f.get(obj);				
						if (list.size() == 0) {
							ok = false;
							Gdx.app.log(tag, "List<region> size = 0 voi : " + f.getName());

						}
					}

				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		return ok;
	}

	public GsnManagerTexture() {
		manager.setLoader(ParticleEffect.class, new GsnParticleLoader(resolver));
	}

	public abstract void loadTexture();

	public abstract void assignTask();

	final public void assignContent() throws GsnException {
		if (assigned)
			return;
		else {
			assigned = true;
			assignTask();
			if (!checkNullContent())
				throw new GsnException("NULL CONTENT");

		}
	}

	final public boolean update() {
		manager.clear();
		return manager.update();
	}

	final public void clear() {
		loaded = false;
		assigned = false;
		manager.clear();
	}

	final public void finishLoading() {
		manager.finishLoading();
	}

	final public void finishLoadingAndAssignContent() throws GsnException {
		manager.finishLoading();
		assignContent();
	}

	final public void loadAll() throws GsnException {
		loadTexture();
		finishLoading();
		assignContent();
	}
	
	final public void dispose(){
		manager.dispose();
		manager = null;		
	}
}
